Trò chơi Tic-Tac-Toe, game đánh caro full source code
53.454 lượt xem;
1 using Assets.Scripts.Network;
2 using Assets.Scripts.Signals;
3 using UnityEngine;
4
5 namespace Assets.Scripts
6 {
7 public class Game : CoreBehaviour, IGameService
8 {
9 public Board board;
10
11 public Signal<Game> OnGameStartSignal { get; private set; }
12
13 public Signal<Game> OnGameResultSignal { get; private set; }
14
15 public Signal OnGameQuitSignal { get; private set; }
16
17 public GameState CurrentState { get; private set; }
18
19 public bool IsPlaying
20 {
21 get { return CurrentState == GameState.Playing; }
22 }
23
24 public Player Player1 { get; private set; }
25
26 public Player Player2 { get; private set; }
27
28 public void PlayOnline()
29 {
30 CurrentState = GameState.Lobby;
31 NetworkService.Connect();
32 }
33
34 public void PlayOffline()
35 {
36 Reset();
37 NewGame();
38 }
39
40 public void NewGame()
41 {
42 board.gameObject.SetActive(true);
43 board.Clear();
44 board.SetPlayer(Seed.Cross);
45 CurrentState = GameState.Playing;
46
47 if (NetworkService.IsConnected)
48 {
49 if (NetworkService.IsMaster)
50 {
51 Player1.Name = NetworkService.PlayerName;
52 Player2.Name = NetworkService.OpponentName;
53
54 Player1.Type = Seed.Cross;
55 Player2.Type = Seed.Nought;
56 board.SetPlayer(Seed.Cross);
57
58 NetworkService.SendNewGameStarted();
59 }
60 else
61 {
62 Player1.Name = NetworkService.OpponentName;
63 Player2.Name = NetworkService.PlayerName;
64
65 Player1.Type = Seed.Nought;
66 Player2.Type = Seed.Cross;
67 board.SetPlayer(Seed.Empty);
68 }
69 }
70
71 OnGameStartSignal.Dispatch(this);
72 }
73
74 public void Quit()
75 {
76 CurrentState = GameState.MainMenu;
77 HideBoard();
78 OnGameQuitSignal.Dispatch();
79
80 if (NetworkService.IsConnected)
81 {
82 NetworkService.Disconnect();
83 }
84 }
85
86 protected override void Awake()
87 {
88 base.Awake();
89
90 OnGameStartSignal = new Signal<Game>();
91 OnGameResultSignal = new Signal<Game>();
92 OnGameQuitSignal = new Signal();
93
94 ServiceLocator.AddService<IGameService>(this);
95 }
96
97 protected override void Start()
98 {
99 base.Start();
100
101 Reset();
102
103 CurrentState = GameState.MainMenu;
104
105 board.Init(OnBoardChange);
106 board.SetPlayer(Seed.Empty);
107 board.gameObject.SetActive(false);
108
109 NetworkService.OnAllPlayersConnectedSignal.AddListener(OnAllPlayersConnected);
110 NetworkService.OnDisconnectedFromMasterSignal.AddListener(OnDisconnectedFromMaster);
111 NetworkService.OnRemoteBoardChangeSignal.AddListener(OnRemoteBoardChange);
112 }
113
114 protected override void OnDestroy()
115 {
116 base.OnDestroy();
117
118 NetworkService.OnAllPlayersConnectedSignal.RemoveListener(OnAllPlayersConnected);
119 NetworkService.OnDisconnectedFromMasterSignal.RemoveListener(OnDisconnectedFromMaster);
120 NetworkService.OnRemoteBoardChangeSignal.RemoveListener(OnRemoteBoardChange);
121
122 ServiceLocator.RemoveService<IGameService>();
123 }
124
125 protected override void Update()
126 {
127 base.Update();
128
129 if (Input.GetKeyDown(KeyCode.Escape))
130 {
131 if (CurrentState == GameState.MainMenu)
132 {
133 Application.Quit();
134 }
135 else
136 {
137 Quit();
138 }
139 }
140 }
141
142 private void Reset()
143 {
144 Player1 = new Player("Player X", 0, Seed.Cross);
145 Player2 = new Player("Player O", 0, Seed.Nought);
146 }
147
148 private void HideBoard()
149 {
150 board.gameObject.SetActive(false);
151 }
152
153 private void OnAllPlayersConnected()
154 {
155 Reset();
156 NewGame();
157 }
158
159 private void OnDisconnectedFromMaster()
160 {
161 Quit();
162 }
163
164 private void OnRemoteBoardChange(Seed seed, int row, int col)
165 {
166 board.SetCell(seed, row, col);
167 }
168
169 private void OnBoardChange(Seed player, int row, int col)
170 {
171 Seed nextPlayer = Seed.Empty;
172
173 if (board.HasWon(player))
174 {
175 switch (player)
176 {
177 case Seed.Cross:
178 CurrentState = GameState.CrossWin;
179 Player1.Score++;
180 break;
181 case Seed.Nought:
182 CurrentState = GameState.NoughtWin;
183 Player2.Score++;
184 break;
185 }
186
187 OnGameResultSignal.Dispatch(this);
188 }
189 else if (board.IsDraw())
190 {
191 CurrentState = GameState.Draw;
192 OnGameResultSignal.Dispatch(this);
193 }
194 else
195 {
196 nextPlayer = player == Seed.Cross ? Seed.Nought : Seed.Cross;
197 }
198
199 board.SetPlayer(nextPlayer);
200
201 if (NetworkService.IsConnected && player == Player1.Type)
202 {
203 board.SetPlayer(Seed.Empty);
204 NetworkService.SendBoardChange(player, row, col);
205 }
206 }
207 }
208 }
2 using Assets.Scripts.Signals;
3 using UnityEngine;
4
5 namespace Assets.Scripts
6 {
7 public class Game : CoreBehaviour, IGameService
8 {
9 public Board board;
10
11 public Signal<Game> OnGameStartSignal { get; private set; }
12
13 public Signal<Game> OnGameResultSignal { get; private set; }
14
15 public Signal OnGameQuitSignal { get; private set; }
16
17 public GameState CurrentState { get; private set; }
18
19 public bool IsPlaying
20 {
21 get { return CurrentState == GameState.Playing; }
22 }
23
24 public Player Player1 { get; private set; }
25
26 public Player Player2 { get; private set; }
27
28 public void PlayOnline()
29 {
30 CurrentState = GameState.Lobby;
31 NetworkService.Connect();
32 }
33
34 public void PlayOffline()
35 {
36 Reset();
37 NewGame();
38 }
39
40 public void NewGame()
41 {
42 board.gameObject.SetActive(true);
43 board.Clear();
44 board.SetPlayer(Seed.Cross);
45 CurrentState = GameState.Playing;
46
47 if (NetworkService.IsConnected)
48 {
49 if (NetworkService.IsMaster)
50 {
51 Player1.Name = NetworkService.PlayerName;
52 Player2.Name = NetworkService.OpponentName;
53
54 Player1.Type = Seed.Cross;
55 Player2.Type = Seed.Nought;
56 board.SetPlayer(Seed.Cross);
57
58 NetworkService.SendNewGameStarted();
59 }
60 else
61 {
62 Player1.Name = NetworkService.OpponentName;
63 Player2.Name = NetworkService.PlayerName;
64
65 Player1.Type = Seed.Nought;
66 Player2.Type = Seed.Cross;
67 board.SetPlayer(Seed.Empty);
68 }
69 }
70
71 OnGameStartSignal.Dispatch(this);
72 }
73
74 public void Quit()
75 {
76 CurrentState = GameState.MainMenu;
77 HideBoard();
78 OnGameQuitSignal.Dispatch();
79
80 if (NetworkService.IsConnected)
81 {
82 NetworkService.Disconnect();
83 }
84 }
85
86 protected override void Awake()
87 {
88 base.Awake();
89
90 OnGameStartSignal = new Signal<Game>();
91 OnGameResultSignal = new Signal<Game>();
92 OnGameQuitSignal = new Signal();
93
94 ServiceLocator.AddService<IGameService>(this);
95 }
96
97 protected override void Start()
98 {
99 base.Start();
100
101 Reset();
102
103 CurrentState = GameState.MainMenu;
104
105 board.Init(OnBoardChange);
106 board.SetPlayer(Seed.Empty);
107 board.gameObject.SetActive(false);
108
109 NetworkService.OnAllPlayersConnectedSignal.AddListener(OnAllPlayersConnected);
110 NetworkService.OnDisconnectedFromMasterSignal.AddListener(OnDisconnectedFromMaster);
111 NetworkService.OnRemoteBoardChangeSignal.AddListener(OnRemoteBoardChange);
112 }
113
114 protected override void OnDestroy()
115 {
116 base.OnDestroy();
117
118 NetworkService.OnAllPlayersConnectedSignal.RemoveListener(OnAllPlayersConnected);
119 NetworkService.OnDisconnectedFromMasterSignal.RemoveListener(OnDisconnectedFromMaster);
120 NetworkService.OnRemoteBoardChangeSignal.RemoveListener(OnRemoteBoardChange);
121
122 ServiceLocator.RemoveService<IGameService>();
123 }
124
125 protected override void Update()
126 {
127 base.Update();
128
129 if (Input.GetKeyDown(KeyCode.Escape))
130 {
131 if (CurrentState == GameState.MainMenu)
132 {
133 Application.Quit();
134 }
135 else
136 {
137 Quit();
138 }
139 }
140 }
141
142 private void Reset()
143 {
144 Player1 = new Player("Player X", 0, Seed.Cross);
145 Player2 = new Player("Player O", 0, Seed.Nought);
146 }
147
148 private void HideBoard()
149 {
150 board.gameObject.SetActive(false);
151 }
152
153 private void OnAllPlayersConnected()
154 {
155 Reset();
156 NewGame();
157 }
158
159 private void OnDisconnectedFromMaster()
160 {
161 Quit();
162 }
163
164 private void OnRemoteBoardChange(Seed seed, int row, int col)
165 {
166 board.SetCell(seed, row, col);
167 }
168
169 private void OnBoardChange(Seed player, int row, int col)
170 {
171 Seed nextPlayer = Seed.Empty;
172
173 if (board.HasWon(player))
174 {
175 switch (player)
176 {
177 case Seed.Cross:
178 CurrentState = GameState.CrossWin;
179 Player1.Score++;
180 break;
181 case Seed.Nought:
182 CurrentState = GameState.NoughtWin;
183 Player2.Score++;
184 break;
185 }
186
187 OnGameResultSignal.Dispatch(this);
188 }
189 else if (board.IsDraw())
190 {
191 CurrentState = GameState.Draw;
192 OnGameResultSignal.Dispatch(this);
193 }
194 else
195 {
196 nextPlayer = player == Seed.Cross ? Seed.Nought : Seed.Cross;
197 }
198
199 board.SetPlayer(nextPlayer);
200
201 if (NetworkService.IsConnected && player == Player1.Type)
202 {
203 board.SetPlayer(Seed.Empty);
204 NetworkService.SendBoardChange(player, row, col);
205 }
206 }
207 }
208 }